package org.app.original.improve;

import java.lang.reflect.Array;
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.app.Ports;

/**
 * bean 转其他格式
 * 通过 实现Port 暂实现 转 json和xml
 * @author zheng
 *
 */
public class MyDecrypt {
	protected String[] ARRAYS=new String[]{"[","]"};
	protected String[] MAPS=new String[]{"{","}"};
	protected String PARALLEL=",";
	
	protected String NUMBER="%s";
	protected String STRING="\"%s\"";
	protected String VALUE="%s",MAP="\"{0}\":{1}";
	protected Ports map;


	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}
	
	<T> StringBuffer toFormat(T t) {
		StringBuffer sb = new StringBuffer();
		if (t == null)
			return sb;
		if (t instanceof Number) {
			sb.append(String.format(NUMBER, t));
		} else if (t instanceof String) {
			sb.append(String.format(STRING, t));
		} else if (t.getClass().getClassLoader() != null) {// 用户自定义类型
			Map map = MyFormat.toMap(t);
			sb.append(toFormat(map));
		} else if (t instanceof Map) {
			// sb.append(t);
			//sb.append("{");
			Map map = (Map) t;
			Set<Entry> set = map.entrySet();
			String[] format=new String[map.size()];
			int id=0;
			for (Entry<String,Object> entry : set) {
				Object value = entry.getValue();
				if (value == null) {
				//	format[id++]="";
					continue;
				}
				
				String name=entry.getKey();
				if(name.equals("class")){
					continue;
				}
				/// sb.append(string).append(entry.getKey()).append(string).append(mapper).append(value).append(parallel);
//				sb.append(String.format("\"%s\":%s,", entry.getKey(),
//						toJSON(entry.getValue())));
				format [id++]=MessageFormat.format(MAP,name,toFormat(entry.getValue()),value.getClass().getName());

			}
			// sb.setCharAt(sb.length()-1, "}");
			// String type=t.getClass().toString().split(" ");

//			sb.append(String
//					.format("\"class\":\"%s\"}", t.getClass().getName()));
			

			if(this.map==null){
			 sb.append(String.format(getFormat(id,MAPS), format));//getFormat(id,MAPS)
			}else{
			sb.append(this.map.execute(map));
			}
		}
		if (t instanceof List) {
			// sb.append(t);

			List list = (List) t;
			int size = list.size();
			if (size <= 0)
				return sb.append("[]");

			// String array=this.getArrayFormat(size);
			String[] format = new String[size];
			for (int i = 0; i < size; i++) {
				// sb.append(String.format("%s,", toJSON(obj)));
				format[i] = String.format(VALUE,toFormat(list.get(i)));
			}

			// sb.setCharAt(sb.length()-1, parallelRight);
			sb.append(String.format(this.getFormat(size,ARRAYS), format));
		}
		if (t.getClass().isArray()) {
			int size = Array.getLength(t);
			if (size <= 0)
				return sb.append("[]");
			String[] format = new String[size];
			for (int i = 0; i < size; i++) {
				// sb.append(String.format("%s,", toJSON(obj)));
				format[i] = toFormat(Array.get(t, i)).toString();
			}

			// sb.setCharAt(sb.length()-1, parallelRight);
			sb.append(String.format(this.getFormat(size,ARRAYS), format));

		}
		return sb;
	}

	
	public String getFormat(int size,String []type){
		StringBuffer sb = new StringBuffer();
		if (size > 0) {
			sb.append(type[0]+"%s");
		} else {
			sb.append(type[0]+type[1]);
			return sb.toString();
		}
		for (int i = 1; i < size; i++) {
			sb.append(PARALLEL+"%s");
		}
		sb.append(type[1]);
		return sb.toString();
	}
	
	public <T> String toFormat(Ports ports,T t){
		return this.toFormat(t).toString();
	}
	
	/**
	 * \"
*\\
*\/
*\b
*\f
*\n
*\r
*\t \\u four-hex-digits
*未处理特殊字符

	 * @param t
	 * @return
	 */
	public <T>String toJSON(T t){
		ARRAYS=new String[]{"[","]"};
		MAPS=new String[]{"{","}"};
		PARALLEL=",";
		STRING="\"%s\"";
		NUMBER="%s";
		MAP="\"{0}\":{1}";
		VALUE="%s";
		toJSONMap();
		return this.toFormat(t).toString();
	}
	
	public <T>String toXML(T t){
		ARRAYS=new String[]{"",""};
		MAPS[0]="<";
		MAPS[1]=">";
		PARALLEL="";
		STRING="%s";
		NUMBER="%s";
		MAP="<{0} class=\"{2}\">{1}</{0}>";
		VALUE="<value>%s</value>";
	    toXMLMap();
		return this.toFormat(t).toString();
	}
	
	public void toXMLMap(){
		map=new Ports(){

			@Override
			public Object execute(Object obj) {
				// TODO Auto-generated method stub
				
				Map map=(Map)obj;
				
				String[] format=mapTo(map);
				
				Class clazz=(Class)map.get("class");
				String name=clazz.getSimpleName();
				String type=clazz.getName();
				StringBuffer sb=new StringBuffer();
				for(String content:format){
					if(content!=null)
					sb.append(content);
				}
				return MessageFormat.format(MAP, name,sb,type);
			}
			
		};
	}
	

	public void toJSONMap(){
		map=new Ports(){

			@Override
			public Object execute(Object obj) {
				// TODO Auto-generated method stub
				
			    String[] format=mapTo((Map)obj);
			    int id=format.length;
			    for(int i=id-1;i>=0;i--){
			    	if(format.equals("")){
			    		id--;
			    	}else
			    		break;
			    }
			    return String.format(getFormat(id,MAPS), format);
			}
			
		};
	}

	public String [] mapTo(Map map){
		
		Set<Entry> set = map.entrySet();
		String[] format=new String[map.size()];
		int id=0;
		for (Entry<String,Object> entry : set) {
			Object value = entry.getValue();
			if (value == null) {
			//	format[id++]="";
				continue;
			}
			
			String name=entry.getKey();
			if(name.equals("class")){
				continue;
			}
			/// sb.append(string).append(entry.getKey()).append(string).append(mapper).append(value).append(parallel);
//			sb.append(String.format("\"%s\":%s,", entry.getKey(),
//					toJSON(entry.getValue())));
			format [id++]=MessageFormat.format(MAP,name,toFormat(entry.getValue()),value.getClass().getName());

		
		}
		
		return format;
	}

}
